package com.test.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import com.test.core.PostService;
import com.test.objects.Author;
import com.test.objects.Category;
import com.test.objects.ConfigObject;
import com.test.objects.MyPageException;
import com.test.objects.Post;
import com.test.objects.PostClass;

public class ViewController extends AbstractController {
	private PostService postService;
	private ConfigObject configObject;
	
	@SuppressWarnings("deprecation")
	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest req,
			HttpServletResponse res) throws Exception {
		
		String pageType = req.getParameter("page") != null ?
				req.getParameter("page") : "";
		Map<String, Object> viewData = new HashMap<String, Object>();

		if (pageType.equals("") || pageType.equals("posts")){
			int postPaging = this.configObject.getPostPaging();
			int numOfRow = this.postService.getPostCount();
			int numOfPage = (int)Math.ceil((double)numOfRow / (double)postPaging);
			
			int page = req.getParameter("p") != null ? 
					Integer.parseInt(req.getParameter("p")) - 1 : 0;		

			Post[] posts = this.postService.
					getPostList(page * postPaging, postPaging);
			
			viewData.put("isEmptyList", posts == null || posts.length == 0);
			if (posts == null || posts.length == 0)
				viewData.put("message", "there is no item found for this request");
			viewData.put("numOfPage", numOfPage);
			viewData.put("posts", posts);
			
			return new ModelAndView("view", viewData);
		}else if (pageType.equals("post-view")){
			int pId = Integer.parseInt(req.getParameter("id"));
			Post post = this.postService.getPost(pId);
			viewData.put("postExist", post != null);
			viewData.put("post", post);
			if (post == null)
				viewData.put("message", 
					"the post with id [" + pId + "] does not exist in the database");
			return new ModelAndView("view", viewData);
		}else if (pageType.equals("posts-cat")){
			int page = req.getParameter("p") != null ? 
					Integer.parseInt(req.getParameter("p")) - 1 : 0;		
			int catId = req.getParameter("id") != null ? 
					Integer.parseInt(req.getParameter("id")) : 0;

			int postPaging = this.configObject.getPostPaging();
			int numOfRow = this.postService.
					getPostCount(PostClass.category, catId);
			int numOfPage = (int)Math.ceil((double)numOfRow / (double)postPaging);
			Category cat = this.postService.getCategory(catId);

			Post[] posts = cat != null ? this.postService.getPostList(
					PostClass.category, catId, page * postPaging, postPaging) : 
					new Post[] {};
			
			viewData.put("isEmptyList", posts == null || posts.length == 0);
			if (posts == null || posts.length == 0)
				viewData.put("message", "there is no item found for this request");
			viewData.put("id", catId);
			viewData.put("category", cat);
			viewData.put("numOfPage", numOfPage);
			viewData.put("posts", posts);
			
			return new ModelAndView("view", viewData);
		}else if (pageType.equals("posts-author")){
			int page = req.getParameter("p") != null ? 
					Integer.parseInt(req.getParameter("p")) - 1 : 0;		
			int authorId = req.getParameter("id") != null ? 
					Integer.parseInt(req.getParameter("id")) : 0;

			int postPaging = this.configObject.getPostPaging();
			int numOfRow = this.postService.
					getPostCount(PostClass.author, authorId);
			int numOfPage = (int)Math.ceil((double)numOfRow / (double)postPaging);
			Author aut = this.postService.getAuthor(authorId);
			
			Post[] posts = aut != null ? this.postService.getPostList(
					PostClass.author, authorId, page * postPaging, postPaging) : 
					new Post[] {};
			
			viewData.put("isEmptyList", posts == null || posts.length == 0);
			if (posts == null || posts.length == 0)
				viewData.put("message", "there is no item found for this request");
			viewData.put("id", authorId);
			viewData.put("author", aut);
			viewData.put("numOfPage", numOfPage);
			viewData.put("posts", posts);
			
			return new ModelAndView("view", viewData);			
		}else if (pageType.equals("post-input")){
			boolean isPageSubmitted = req.getMethod().equalsIgnoreCase("post");
			viewData.put("isPageSubmitted", isPageSubmitted);
			
			HttpSession currSession = req.getSession();
			Author author = (Author)currSession.getAttribute("author");
			if (author != null){
				viewData.put("author", author);
			}else{
				viewData.put("accessDenied", true);
				viewData.put("message", 
					"<font color=\"ff0000\">you don't have permission to access this page!</font>");
				return new ModelAndView("view", viewData);
			}
			
			if (isPageSubmitted){
				String rootPath = req.getRealPath("/");
				this.postService.setAppLocation(rootPath);
				
				Post prepost = new Post();
				prepost.setTitle(req.getParameter("post_title"));
				
				Category cat = new Category();
				cat.setId(Integer.parseInt(req.getParameter("post_cat")));
				prepost.setCategory(cat);
				
				Author aut = new Author();
				aut.setId(Integer.parseInt(req.getParameter("post_author")));
				prepost.setAuthor(aut);
				
				prepost.setSummary(req.getParameter("post_summary"));
				prepost.setImageUrl(req.getParameter("post_imgurl"));
				prepost.setContent(req.getParameter("post_content"));
				prepost.setDateTime(new Date());
				try {
					int newPostId = this.postService.savePost(prepost);
					viewData.put("message", 
						"<ul>" +
						"<li>insert a post to database successfully.<br>" + 
						"<li>view <a href=\"view.m?page=post-view&id=" + newPostId + "\">this post</a>" + 
						"</ul>");
					viewData.put("isSucess", true);
				}catch(MyPageException ex){
					viewData.put("message", 
						"<font color=\"#ff0000\">post can not be added: " + ex.getMessage() + "</font>");
					viewData.put("isSucess", false);
				}
				
				return new ModelAndView("view", viewData);
			}else{
				Category[] cats = this.postService.getCategories();
				viewData.put("cats", cats);
				
				return new ModelAndView("view", viewData);
			}
		}else if (pageType.equals("post-update")){
			String action = req.getParameter("action");
			int postId = Integer.parseInt(req.getParameter("id"));
			if (action.equals("edit")){
				
			}else if (action.equals("del")){
				int row_effect = this.postService.deletePost(postId);
				viewData.put("message", row_effect > 0 ?
					"the post is permanently deleted from the database" : 
					"the post can not be delete");
			}
			
			viewData.put("action", action);
			viewData.put("postId", postId);
			return new ModelAndView("view", viewData);
		}else if (pageType.equals("help")){
			return new ModelAndView("view", viewData);
		}
		return null;
	}
	
	public void setPostService(PostService postSvr){
		this.postService = postSvr;
	}
	
	public void setConfigObject(ConfigObject configObj){
		this.configObject = configObj;
	}
}
